/**
 * 
 */
package com.goktech.commons.excel;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.goktech.commons.utils.StringUtils;

/**
 * excel导出样式解析器
 * 
 * @author echoyu on 2017年10月27日
 *
 */
public class ExcelStyleResolver implements ExcelStyle {

	private final static Logger logger = LoggerFactory.getLogger(ExcelStyleResolver.class);

	private final static String DEFAULT = "DEFAULT";

	private final static String TITLE = "TITLE";

	private Class<?> clazz;

	private Workbook workbook;

	private Map<String, CellStyle> cache;

	private Style defaultStyle;

	private Map<String, Style> fieldStyle;

	private Map<Style, CellStyle> _cache;

	public ExcelStyleResolver(Class<?> clazz, Workbook workbook) {
		super();
		this.clazz = clazz;
		this.workbook = workbook;
		this.cache = new HashMap<String, CellStyle>(2);
		fieldStyle = new HashMap<>();
		scanner();
	}

	public void style(CellStyle cellStyle, Font font, com.goktech.commons.excel.Font Afont, Style style) {

		// 设置底边框;
		cellStyle.setBorderBottom(style.borderBottom());
		// 设置底边框颜色;
		cellStyle.setBottomBorderColor(style.bottomBorderColor().getIndex());
		// 设置左边框;
		cellStyle.setBorderLeft(style.borderLeft());
		// 设置左边框颜色;
		cellStyle.setLeftBorderColor(style.leftBorderColor().getIndex());
		// 设置右边框;
		cellStyle.setBorderRight(style.borderRight());
		// 设置右边框颜色;
		cellStyle.setRightBorderColor(style.rightBorderColor().getIndex());
		// 设置顶边框;
		cellStyle.setBorderTop(style.borderTop());
		// 设置顶边框颜色;
		cellStyle.setTopBorderColor(style.topBorderColor().getIndex());
		// 在样式用应用设置的字体;
		font.setFontName(Afont.fontName());
		font.setItalic(Afont.italic());
		font.setFontHeight(Afont.fontHeight());
		font.setFontHeightInPoints(Afont.fontHeightInPoints());

		cellStyle.setFont(font);

		cellStyle.setFont(font);
		// 设置自动换行;
		cellStyle.setWrapText(false);
		// 设置水平对齐的样式为居中对齐;
		cellStyle.setAlignment(style.alignment());
		// 设置垂直对齐的样式为居中对齐;
		cellStyle.setVerticalAlignment(style.verticalAlignment());

		cellStyle.setFillBackgroundColor(style.fillBackgroundColor().getIndex());

		cellStyle.setFillForegroundColor(style.fillForegroundColor().getIndex());

		cellStyle.setFillPattern(style.fillPattern());

	}

	@Override
	public synchronized CellStyle getDefaultStyle() {
		if (cache.get(DEFAULT) == null) {
			CellStyle cellStyle = this.workbook.createCellStyle();
			if (defaultStyle == null) {
				cache.put(DEFAULT, cellStyle);
				return cellStyle;
			}
			Font font = this.workbook.createFont();
			style(cellStyle, font, defaultStyle.font(), defaultStyle);
			cache.put(DEFAULT, cellStyle);
		}
		return cache.get(DEFAULT);
	}

	@Override
	public CellStyle getTitleStyle(String name) {
		Style style = this.fieldStyle.get(name);
		if (style == null) {
			return this.getDefaultStyle();
		}
		return this.getStyle(style);
	}

	@Override
	public CellStyle getStyle(Style style) {
		if (_cache == null) {
			_cache = new HashMap<>();
		}
		if (_cache.get(style) == null) {
			CellStyle cellStyle = this.workbook.createCellStyle();
			Font font = this.workbook.createFont();
			if(StringUtils.isEmpty(style.id())){
				style(cellStyle, font, style.font(), style);
			}else{
				return this.getStyle(style.id());
			}
			_cache.put(style, cellStyle);
		}
		return _cache.get(style);
	}

	/**
	 * 扫描style注解
	 */
	private void scanner() {
		this.defaultStyle = this.clazz.getAnnotation(Style.class);
		getProperty(this.clazz);
		if (logger.isDebugEnabled()) {
			logger.debug("样式容器初始化成功");
		}
		Row row = this.clazz.getAnnotation(Row.class);
		if(row != null){
			saveCellStyle(row.cells());
		}
		Styles styles = this.clazz.getAnnotation(Styles.class);
		if(styles != null){
			saveCellStyle(styles.styles());
		}
		// 对标题注解的扫描结果进行判断，
		int styleNumber = 0;
		Style style = null;
		for (String key : fieldStyle.keySet()) {
			if (null != fieldStyle.get(key)) {
				style = fieldStyle.get(key);
				styleNumber++;
			}
		}
		if (logger.isDebugEnabled())
			logger.debug("styleNumber : {}", styleNumber);
		if (styleNumber == fieldStyle.size()) {
			return;
		}

		if (styleNumber == 1) {
			for (String key : fieldStyle.keySet()) {
				fieldStyle.put(key, style);
			}
			return;
		}
		// 全部设置默认样式
		if (styleNumber == 0) {
			for (String key : fieldStyle.keySet()) {
				fieldStyle.put(key, defaultStyle);
			}
			return;
		}
		// 将空的设置默认样式
		for (String key : fieldStyle.keySet()) {
			if (null == fieldStyle.get(key))
				fieldStyle.put(key, defaultStyle);
		}
	}

	private void getProperty(Class<?> clazz) {
		Field[] fields = clazz.getDeclaredFields();
		if (fields.length <= 0) {
			return;
		}
		for (Field field : fields) {
			Style obj = field.getAnnotation(Style.class);
			this.fieldStyle.put(field.getName(), obj);
		}
		getProperty(clazz.getSuperclass());
	}

	@Override
	public CellStyle getStyle(CellStyle cellStyle) {
		// 设置底边框;
		cellStyle.setBorderBottom(cellStyle.getBorderBottom());
		// 设置底边框颜色;
		cellStyle.setBottomBorderColor(cellStyle.getBottomBorderColor());
		// 设置左边框;
		cellStyle.setBorderLeft(cellStyle.getBorderLeft());
		// 设置左边框颜色;
		cellStyle.setLeftBorderColor(cellStyle.getLeftBorderColor());
		// 设置右边框;
		cellStyle.setBorderRight(cellStyle.getBorderRight());
		// 设置右边框颜色;
		cellStyle.setRightBorderColor(cellStyle.getRightBorderColor());
		// 设置顶边框;
		cellStyle.setBorderTop(cellStyle.getBorderTop());
		// 设置顶边框颜色;
		cellStyle.setTopBorderColor(cellStyle.getTopBorderColor());

		// 设置自动换行;
		cellStyle.setWrapText(cellStyle.getWrapText());
		// 设置水平对齐的样式为居中对齐;
		cellStyle.setAlignment(cellStyle.getAlignment());
		// 设置垂直对齐的样式为居中对齐;
		cellStyle.setVerticalAlignment(cellStyle.getVerticalAlignment());

		cellStyle.setFillBackgroundColor(cellStyle.getFillBackgroundColor());

		cellStyle.setFillForegroundColor(cellStyle.getFillForegroundColor());
		cellStyle.setFillPattern(cellStyle.getFillPattern());
		return cellStyle;
	}

	private void saveCellStyle(Cell[] cells) {
		for(Cell cell : cells){
			saveCellStyle(cell);
		}
	}

	private void saveCellStyle(Cell cell) {
			String id = cell.id();
			if(StringUtils.isEmpty(id)){
				id = DEFAULT;
			}
			Style style = cell.style();
			CellStyle cellStyle = this.workbook.createCellStyle();
			style(cellStyle,this.workbook.createFont(),style.font(),style);
			cache.put(id, cellStyle);
			
	}

	private void saveCellStyle(Style[] styles) {
		for(Style style : styles){
			saveCellStyle(style);
		}
	}

	private void saveCellStyle(Style style) {
			String id = style.id();
			if(StringUtils.isEmpty(id)){
				throw new NullPointerException("Styles 注解里面的 style 的id 不能为空");
			}
			CellStyle cellStyle = this.workbook.createCellStyle();
			style(cellStyle,this.workbook.createFont(),style.font(),style);
			cache.put(id, cellStyle);
			
	}
	
	@Override
	public CellStyle getStyle(String id) {
		CellStyle cellStyle = null;
		if(StringUtils.isEmpty(id)){
			cellStyle = this.cache.get(DEFAULT);
		}else{
			cellStyle = this.cache.get(id);
		}
		if(cellStyle == null){
			cellStyle = this.getDefaultStyle();
		}
		return cellStyle;
	}
	
}
